home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-11-22 | 10.2 KB | 362 lines | [TEXT/CWIE] |
- /*
- Class_DynamoArray.cpp
-
- Version 2.0
- (c)1993, 1994, 1995 by Hiep Dam. All Rights Reserved.
- From The Witches' Brew
-
- Usage: Public domain. Feel free to exploit it to your own needs; it would
- be nice of you, however, to give me some tiny credits if you decide
- to use this in your application or if the code helps you...
- */
-
- // ---------------------------------------------------------------------------
-
- #include "Class_DynamoArray.h"
-
- const short STD_DYNAMO_LEN = 10; // The standard chunk length the array grows by
-
- // ---------------------------------------------------------------------------
-
- #pragma mark === CTORs/DTORs ===
-
- template <class DynamoArrayType>
- DynamoArray<DynamoArrayType>::DynamoArray() {
- // Default constructor; no arguments.
- // This constructor just creates an array with the default size
- // of STD_DYNAMO_LEN (i.e. 10). You can change the standard
- // default size by changing STD_DYNAMO_LEN, if you wish.
- fMaxSize = STD_DYNAMO_LEN;
- fCurSize = 0;
- fArray = new DynamoArrayType[fMaxSize];
- } // END constructor
-
- // ---------------------------------------------------------------------------
-
- template <class DynamoArrayType>
- DynamoArray<DynamoArrayType>::DynamoArray(short size) {
- if (size < 1) {
- fMaxSize = STD_DYNAMO_LEN;
- fCurSize = 0;
- fArray = new DynamoArrayType[fMaxSize];
- }
- else {
- fMaxSize = size;
- fCurSize = 0;
- fArray = new DynamoArrayType[fMaxSize];
- }
- } // END constructor
-
- // ---------------------------------------------------------------------------
-
- template <class DynamoArrayType>
- DynamoArray<DynamoArrayType>::~DynamoArray() {
- if (fArray != NULL)
- delete []fArray;
- } // END destructor
-
- // ---------------------------------------------------------------------------
-
- template <class DynamoArrayType>
- void DynamoArray<DynamoArrayType>::IncreaseSize() {
- // Increase array length/size
- fMaxSize += STD_DYNAMO_LEN;
-
- // Now create newly-sized array
- DynamoArrayType *temp = new DynamoArrayType[fMaxSize];
- if (temp == NULL) {
- // Insert c++ exception here.
- }
-
- // Copy items from old array into newly-created array
- for (short i = 0; i < fCurSize; i++)
- temp[i] = fArray[i];
-
- // Delete original copy.
- delete fArray;
-
- fArray = temp;
- } // END IncreaseSize
-
- //-------------------------------------------------------------
-
- // Copy *Constructor*. Remember, this is a constructor
- // so the fields of the array are invalid when we begin
-
- template <class DynamoArrayType>
- DynamoArray<DynamoArrayType>::DynamoArray(DynamoArray& sourceArray) {
- if (&sourceArray == this) return; // Don't copy with references to self
-
- fCurSize = sourceArray.fCurSize;
- fMaxSize = 0;
-
- while (fMaxSize < fCurSize)
- fMaxSize += STD_DYNAMO_LEN; // Increase it in chunks of STD_DYNAMO_LEN
-
- fArray = new DynamoArrayType[fMaxSize];
- if (fArray == NULL) {
- // Insert c++ exception here
- }
-
- for (short i = 0; i < fCurSize; i++)
- fArray[i] = sourceArray.fArray[i];
- } // END Copy constructor
-
- //-------------------------------------------------------------
-
- #pragma mark === Operators ===
-
- // Assignment operator (overloaded)
-
- template <class DynamoArrayType>
- DynamoArray DynamoArray<DynamoArrayType>::operator=(const DynamoArray& sourceArray) {
- if (&sourceArray == this) return(*this); // Don't assign with references to self
-
- // Make a copy, so trash whatever we have currently. Unfortunately
- // we can't make a call to the destructor, so we have to do this manually...
- delete []fArray;
-
- // Now make a new array
- fArray = new DynamoArrayType[fMaxSize = sourceArray.fMaxSize];
- if (fArray == NULL) {
- // Insert c++ exception here
- }
- fCurSize = sourceArray.fCurSize;
-
- // Do the actual copy...
- for (short i = 0; i < fCurSize; i++)
- fArray[i] = sourceArray.fArray[i];
-
- return(*this); // return a copy of this object
- } // END Assignment operator
-
- //-------------------------------------------------------------
-
- template <class DynamoArrayType>
- DynamoArrayType *DynamoArray<DynamoArrayType>::operator[] (short index) {
- if ((index < 0) || (index >= fCurSize))
- return NULL;
- else
- return &fArray[index];
- } // END operator[]
-
- //-------------------------------------------------------------
-
- #pragma mark === Member Funcs ===
-
- template <class DynamoArrayType>
- void DynamoArray<DynamoArrayType>::Preallocate(short size) {
- /* This makes the array the specified size; note that
- the old array is destroyed - it's contents are lost.
- So make sure you call this first before adding any
- data to the array.
- */
-
- delete []fArray;
-
- // Make it a little bigger, just in case
- fMaxSize = size + STD_DYNAMO_LEN;
-
- fArray = new DynamoArrayType[fMaxSize];
- if (fArray == NULL) {
- // Oops. Insert c++ exception here.
- }
-
- fCurSize = 0;
- } // END Preallocate
-
- //-------------------------------------------------------------
-
- template <class DynamoArrayType>
- short DynamoArray<DynamoArrayType>::Get(DynamoArrayType& theItem, short index) {
- if ((index < 0) || (index >= fCurSize) || (fArray == NULL))
- // Check for correct boundaries...
- return(kDynamoArrayOutOfBoundsErr);
- else {
- theItem = fArray[index];
- return(index);
- }
- } // END GetItem
-
- //-------------------------------------------------------------
-
- template <class DynamoArrayType>
- short DynamoArray<DynamoArrayType>::RandomGet(DynamoArrayType& theItem) {
- if (fCurSize > 0) {
- // Get a random value.
- short randomVal = GetRandom(0, fCurSize - 1);
- // Now retrieve the item.
- short returnVal = Get(theItem, randomVal);
-
- // Did something go wrong? If no...
- if (returnVal >= 0)
- return(randomVal);
- else
- // Ooops, something went wrong; return error value.
- return(returnVal);
- }
- else
- // Oops, array empty.
- return(kDynamoArrayOutOfBoundsErr);
- } // END RandomGet
-
- //-------------------------------------------------------------
-
- template <class DynamoArrayType>
- short DynamoArray<DynamoArrayType>::Append(const DynamoArrayType& theItem) {
- if (fArray == NULL) {
- // If array empty, create new one.
- fMaxSize = STD_DYNAMO_LEN;
- fCurSize = 1;
- fArray = new DynamoArrayType[fMaxSize];
- }
- else {
- if (fCurSize == fMaxSize)
- // Ooh, we reached the maximum size. Time to enlarge
- // the array.
- IncreaseSize();
- // We're going to add an item, so increment fCurSize
- fCurSize++;
- }
-
- // Put item into the array.
- fArray[fCurSize - 1] = theItem;
- // Return index value of item we appended into array.
- return(fCurSize - 1);
- } // END Append
-
- //-------------------------------------------------------------
-
- template <class DynamoArrayType>
- short DynamoArray<DynamoArrayType>::Insert(const DynamoArrayType& theItem, short index) {
- if ((index < 0) || (index > fCurSize) || (fArray == NULL))
- return(kDynamoArrayOutOfBoundsErr);
-
- if (fCurSize + 1 == fMaxSize)
- // Reached maximum size, so enlarge the array.
- IncreaseSize();
-
- // OK, make room for our new item! Shift everything down from
- // location on to the end of the array.
- for (short i = fCurSize - 1; i >= index; i--)
- fArray[i + 1] = fArray[i];
-
- // Add our new item.
- fArray[index] = theItem;
-
- // We're adding an item, so increment the number of items in array.
- fCurSize++;
-
- return(index); // Everything OK, so return index value.
- } // END Insert
-
- //-------------------------------------------------------------
-
- template <class DynamoArrayType>
- short DynamoArray<DynamoArrayType>::Delete(short index) {
- if ((index < 0) || (index >= fCurSize) || (fArray == NULL))
- return(kDynamoArrayOutOfBoundsErr);
-
- // Shift array backwards (down to 0), so we don't lose anything.
- // If user specified last item is the item to be deleted, this loop
- // won't execute. We just decrement fCurSize instead.
- for (short i = index + 1; i < fCurSize; i++)
- fArray[i - 1] = fArray[i];
-
- fCurSize--;
- return(index);
- } // END Delete
-
- //-------------------------------------------------------------
-
- template <class DynamoArrayType>
- short DynamoArray<DynamoArrayType>::SearchDelete(DynamoArrayType& theItem, short startIndex) {
- short val = kDynamoArrayOutOfBoundsErr; // Assume did not find item
-
- // Search for the item by value, not by index.
- val = Search(theItem, startIndex);
- if (val >= 0)
- Delete(val); // We found it, so delete!
-
- return val;
- } // END SearchDelete
-
- //-------------------------------------------------------------
-
- template <class DynamoArrayType>
- short DynamoArray<DynamoArrayType>::Remove(DynamoArrayType& theItem, short index) {
- if ((index < 0) || (index >= fCurSize) || (fArray == NULL))
- return(kDynamoArrayOutOfBoundsErr);
- else {
- // In previous versions, Remove() just returned the address of the item
- // that was "deleted". Problem was, the address was no longer pointing
- // to the item that was deleted, but pointed to the item replacing
- // the deleted item!!
- if (Get(theItem, index) != kDynamoArrayOutOfBoundsErr) {
- if (Delete(index) != kDynamoArrayOutOfBoundsErr) {
- return(index);
- }
- }
- return(kDynamoArrayOutOfBoundsErr);
- }
- } // END Remove
-
- //-------------------------------------------------------------
-
- template <class DynamoArrayType>
- short DynamoArray<DynamoArrayType>::RandomRemove(DynamoArrayType& theItem) {
- return Remove(theItem, GetRandom(0, fCurSize - 1));
- } // END RandomRemove
-
- //-------------------------------------------------------------
-
- template <class DynamoArrayType>
- short DynamoArray<DynamoArrayType>::Search(const DynamoArrayType& source, short startIndex) {
- // Assume we haven't found our baby...
- short foundItem = kDynamoArrayOutOfBoundsErr;
-
- if (startIndex >= fCurSize)
- return(foundItem);
-
- for (short i = startIndex; i < fCurSize; i++) {
- if (fArray[i] == source) {
- // Yeah, found it. Set return value and exit loop.
- foundItem = i;
- break;
- }
- }
- return(foundItem);
- } // END Search
-
-
- // -----------------------------------------------------------------------------
-
- // The following routine was "lifted" from Tony Myles' SpriteWorld Package,
- // in GameUtils.c
- // Great code in SpriteWorld, by the way.
-
-
- // By: Tony Myles
- // Date: 9/19/90
- // Copyright: © 1991-93 Tony Myles, All rights reserved worldwide.
-
- // GetRandom
- // generate a random number between min and max inclusive
- template <class DynamoArrayType>
- unsigned short DynamoArray<DynamoArrayType>::GetRandom(unsigned short min, unsigned short max)
- {
- unsigned short random;
- long range, temp;
-
- random = Random();
- range = (max - min) + 1;
- temp = (random * range) / 65536;
- random = temp + min;
-
- return random;
- }
-
- // -----------------------------------------------------------------------------
-
-
- // END DynamoArray.c++